local Aloft = Aloft
if not Aloft then return end

local AloftCastBar = Aloft:GetModule("CastBar", true)
if not AloftCastBar then return end

-----------------------------------------------------------------------------

local AloftSpellIcon = Aloft:NewModule("SpellIcon", Aloft, "AceEvent-3.0")

-----------------------------------------------------------------------------

AloftSpellIcon.namespace = "spellIcon"
AloftSpellIcon.defaults =
{
	profile =
	{
		enable			= true,
		point			= "LEFT",
		relativeToPoint	= "LEFT",
		offsetX			= 0,
		offsetY			= 0,
		size			= 11,

		nointerShield	= true,
		nointerStyle	= "SQUARE",
		nointerColor		= { 1.0, 1.0, 1.0, 0.65 }, -- white
	},
}

-----------------------------------------------------------------------------

-- textures for shield graphic
local noInterruptTexture =
{
	["ROUND"]	= [[Interface\Addons\Aloft\Textures\RndNoInterrupt]],
	["SQUARE"]	= [[Interface\Addons\Aloft\Textures\SqrNoInterrupt]],
}

-- determines how shield graphic scales with spell icon
local noInterruptSize =
{
	["ROUND"]	= { w = 2.5, h = 2.5, },
	["SQUARE"]	= { w = 2.5, h = 2.5, },
}

local nointerruptRegion

-----------------------------------------------------------------------------

function AloftSpellIcon:UpdateAll()
	-- nothing to do
end

-----------------------------------------------------------------------------

function AloftSpellIcon:OnInitialize()
	if self.db ~= Aloft.AloftDB:GetNamespace(self.namespace, true) then self.db = Aloft.AloftDB:RegisterNamespace(self.namespace, self.defaults) end
end

function AloftSpellIcon:OnEnable()
	self:UnregisterAllEvents()
	self:UnregisterAllMessages()
	self:CancelAllTimers()

	self:RegisterMessage("Aloft:OnNameplateHide", "OnNameplateHide")
	self:RegisterMessage("Aloft:OnCastFrameShow", "OnCastFrameShow")
	self:RegisterMessage("Aloft:OnCastFrameHide", "OnCastFrameHide")
	self:RegisterMessage("Aloft:OnCastBarValueChanged", "OnCastBarValueChanged")
	self:UpdateAll()
end

function AloftSpellIcon:OnDisable()
	self:UnregisterAllEvents()
	self:UnregisterAllMessages()
	self:CancelAllTimers()

	for aloftData in Aloft:IterateNameplates() do
		local spellIconRegion = aloftData.spellIconRegion

		spellIconRegion:ClearAllPoints()
		spellIconRegion:SetPoint("CENTER", aloftData.nameplateFrame, "BOTTOMLEFT", 13.33, 10.29)
		spellIconRegion:SetWidth(14.5)
		spellIconRegion:SetHeight(14.5)
		spellIconRegion:SetParent(aloftData.nameplateFrame)

		if nointerruptRegion then
			nointerruptRegion:Hide()
		end
	end
end

function AloftSpellIcon:OnNameplateShow(message, aloftData)
end

function AloftSpellIcon:OnNameplateHide(message, aloftData)
	if aloftData.isTarget or aloftData:IsTarget() then
		self:OnCastFrameHide(message, aloftData)
	end
end

-- TODO: propagate this to name text, level text, boss icon, and/or other "default" nameplate components as needed
function AloftSpellIcon:GetInset(aloftData, noInterrupt)
	if noInterrupt then
		return ((AloftCastBar.db.profile.border ~= "None") and 4) or 0
	else
		return ((AloftCastBar.db.profile.nointerBorder ~= "None") and 4) or 0
	end
end

function AloftSpellIcon:OnCastFrameShow(message, aloftData)
	-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameShow(): enter " .. tostring(aloftData.name))
	-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameShow(): enter " .. tostring(aloftData.name) .. "/" .. tostring(aloftData) .. "/" .. tostring(aloftData.layoutFrame) .. "/" .. tostring(nointerruptRegion) .. "/" .. tostring(aloftData.spellIconRegion))

	if self.db.profile.enable then
		local castFrame = AloftCastBar:GetCastFrame()
		if castFrame then
			local spellIconRegion = aloftData.spellIconRegion
			spellIconRegion:SetParent(castFrame)
			spellIconRegion:SetWidth(self.db.profile.size)
			spellIconRegion:SetHeight(self.db.profile.size)
			spellIconRegion:SetDrawLayer("OVERLAY")
			spellIconRegion:SetBlendMode("BLEND")

			local inset = self:GetInset(aloftData, castFrame.noInterrupt)
			local hinset, vinset = self:AdjustFrame(inset, self.db.profile.relativeToPoint)

			self:PlaceFrame(spellIconRegion, castFrame, self.db.profile, hinset, vinset)

			if self.db.profile.nointerShield then
				if not nointerruptRegion then
					nointerruptRegion = castFrame:CreateTexture(nil, "BORDER")
					-- nointerruptRegion:SetDrawLayer("BORDER")
					nointerruptRegion:SetBlendMode("BLEND")
					nointerruptRegion:SetParent(castFrame)
				end

				-- the nointerrupt graphic is a shield-like graphic that scales with the spell icon, and center on the spell icon.
				local texture = noInterruptTexture[self.db.profile.nointerStyle]

				nointerruptRegion:SetTexture(texture)
				nointerruptRegion:SetVertexColor(unpack(self.db.profile.nointerColor))
		
				nointerruptRegion:ClearAllPoints()
				nointerruptRegion:SetWidth(noInterruptSize[self.db.profile.nointerStyle].w * self.db.profile.size)
				nointerruptRegion:SetHeight(noInterruptSize[self.db.profile.nointerStyle].h * self.db.profile.size)
				nointerruptRegion:SetPoint("CENTER", spellIconRegion, "CENTER", 0, 0)
				nointerruptRegion:SetAlpha(1.0)

				-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameShow() show nointerruptRegion " .. tostring(nointerruptRegion:IsVisible()) .. "/" .. tostring(nointerruptRegion:IsShown()) .. "/" .. tostring(nointerruptRegion:GetParent() and nointerruptRegion:GetParent():IsVisible()) .. "/" .. tostring(nointerruptRegion:GetParent() and nointerruptRegion:GetParent():IsShown()) .. "/" .. tostring(texture) .. "/" .. tostring(nointerruptRegion:GetTexture()))
			end
			-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameShow(): noInterrupt " .. tostring(castFrame.noInterrupt))
		end
		-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameShow(): layout " .. tostring(aloftData.name) .. "/" .. tostring(aloftData) .. "/" .. tostring(layoutFrame) .. "/" .. tostring(nointerruptRegion) .. "/" .. tostring(spellIconRegion))
		-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameShow(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.layoutFrame and aloftData.layoutFrame:GetFrameLevel()) .. "/" .. tostring(castFrame and castFrame:GetFrameLevel()))
	end
end

function AloftSpellIcon:OnCastFrameHide(message, aloftData)
	local spellIconRegion = aloftData.spellIconRegion

	if nointerruptRegion then
		nointerruptRegion:Hide()
	end
	if spellIconRegion then
		spellIconRegion:SetParent(aloftData.nameplateFrame) -- re-associate this with the nameplateFrame
		spellIconRegion:Hide()
	end
end

function AloftSpellIcon:OnCastBarValueChanged(message, aloftData)
	if self.db.profile.enable and AloftCastBar:IsDisplayEnabled() then
		local spellIconRegion = aloftData.spellIconRegion

		 if spellIconRegion or nointerruptRegion then
			local castFrame = AloftCastBar:GetCastFrame()
			if  (not aloftData.alphaOverride or aloftData.alphaOverride > 0) and castFrame and castFrame:IsVisible() --[[ and castFrame:GetParent() == aloftData.nameplateFrame ]] then
				-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameShow(): " .. tostring(aloftData.name) .. "/" .. tostring(spellIconRegion) .. "/" .. tostring(nointerruptRegion) .. "/" .. tostring(castFrame.noInterrupt))

				if spellIconRegion then
					spellIconRegion:SetParent(castFrame) -- NOTE: looks like Blizzard may re-assemble this region on every frame; have to re-associate the spell icon region regularly
					-- TODO: just replace the spell icon region, make it a singleton on the cast frame, and initialize it with the texture from the nameplate region on show?
					-- spellIconRegion:SetDrawLayer("OVERLAY")
					spellIconRegion:Show()
				end
				if nointerruptRegion then
					if castFrame.noInterrupt and self.db.profile.nointerShield then
						nointerruptRegion:Show()
					else
						nointerruptRegion:Hide()
					end
				end
				return
			else
				-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastFrameHide(): " .. tostring(aloftData.name) .. "/" .. tostring(aloftData.layoutFrame and aloftData.layoutFrame:GetFrameLevel()) .. "/" .. tostring(castFrame and castFrame:GetFrameLevel()))
			end
		end
	else
		-- ChatFrame7:AddMessage("AloftSpellIcon:OnCastBarValueChanged(): disabled")
	end

	self:OnCastFrameHide(message, aloftData)
end

-----------------------------------------------------------------------------
